package com.kawa.kemanage.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kawa.kemanage.entity.AdCampaign;
import com.kawa.kemanage.exception.BadSqlException;
import com.kawa.kemanage.mapper.AdCampaignMapper;
import com.kawa.kemanage.mapper.AdvertiserMapper;
import com.kawa.kemanage.service.AdCampaignService;
import com.kawa.kemanage.util.PageResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 广告计划服务实现类
 */
@Service
public class AdCampaignServiceImpl implements AdCampaignService {
    private static final Logger log = LoggerFactory.getLogger(AdCampaignServiceImpl.class);

    @Autowired
    private AdCampaignMapper adCampaignMapper;

    @Autowired
    private AdvertiserMapper advertiserMapper;

    @Override
    public List<AdCampaign> findAll()  {
        try {
            return adCampaignMapper.findAll();
        } catch (Exception e) {
            log.error("查询所有广告计划失败", e);
        }
        return null;
    }

    @Override
    public PageResult<AdCampaign> findByPage(Integer page, Integer size)  {
        try {
            // 计算偏移量
            int offset = (page - 1) * size;
            // 获取总记录数
            long total = adCampaignMapper.count();
            // 获取当前页数据
            List<AdCampaign> records = adCampaignMapper.findByPage(offset, size);
            records.forEach(record -> {
                record.setAdvertiser(advertiserMapper.findById(record.getAdvertiserId()));
            });
            // 返回分页结果
            return PageResult.of(records, total, size, page);
        } catch (Exception e) {
            log.error("分页查询广告计划失败", e);
        }
        return null;
    }

    @Override
    public AdCampaign findById(Integer id)  {
        try {
            AdCampaign campaign = adCampaignMapper.findById(id);
            if (campaign == null) {
                throw new RuntimeException("广告计划不存在");
            }
            return campaign;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询广告计划详情失败", e);
        }
        return null;
    }

    @Override
    public PageResult<AdCampaign> findByAdvertiserIdAndPage(Integer advertiserId, Integer page, Integer size)  {
        try {
            // 计算偏移量
            int offset = (page - 1) * size;
            // 获取总记录数
            long total = adCampaignMapper.countByAdvertiserId(advertiserId);
            // 获取当前页数据
            List<AdCampaign> records = adCampaignMapper.findByAdvertiserIdAndPage(advertiserId, offset, size);
            // 返回分页结果
            return PageResult.of(records, total, size, page);
        } catch (Exception e) {
            log.error("分页查询广告主的广告计划失败", e);
        }
        return null;
    }

    @Override
    @Transactional
    public AdCampaign create(AdCampaign campaign)  {
        try {
            validateCampaign(campaign);
            adCampaignMapper.insert(campaign);
            return campaign;
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("创建广告计划失败", e);
        }
        return null;
    }

    @Override
    @Transactional
    public AdCampaign update(Integer id, AdCampaign campaign)  {
        try {
            if (!adCampaignMapper.existsById(id)) {
                throw new RuntimeException("广告计划不存在");
            }
            validateCampaign(campaign);
            campaign.setCampaignId(id);
            adCampaignMapper.update(campaign);
            return campaign;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新广告计划失败", e);
        }
        return null;
    }

    @Override
    @Transactional
    public void delete(Integer id) {
        try {
            if (!adCampaignMapper.existsById(id)) {
                throw new RuntimeException("广告计划不存在");
            }
            if(adCampaignMapper.finishById(id)){
                // 使用逻辑删除替代物理删除
                adCampaignMapper.logicDelete(id);
            }else {
                throw new RuntimeException("广告计划未完成");
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除广告计划失败", e);
        }
    }

    public PageInfo<AdCampaign> findAllByPage(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        PageInfo<AdCampaign> resultPageInfo;
        try {
            resultPageInfo = new PageInfo<>(adCampaignMapper.findAll());
        }  catch (Exception e) {
            resultPageInfo = new PageInfo<>(null);
            log.error("分页查询有问题", e);
        }
        return resultPageInfo;
    }

    private void validateCampaign(AdCampaign campaign)  {
        try {
            // 验证广告主是否存在
            if (advertiserMapper.findById(campaign.getAdvertiserId()) == null) {
                throw new IllegalArgumentException("广告主不存在");
            }

            // 验证时间
            if (campaign.getStartTime() != null && campaign.getEndTime() != null &&
                campaign.getEndTime().isBefore(campaign.getStartTime())) {
                throw new IllegalArgumentException("结束时间不能早于开始时间");
            }

            // 验证预算
            if (campaign.getBudget() != null && campaign.getBudget().doubleValue() < 0) {
                throw new IllegalArgumentException("预算不能为负数");
            }

            // 验证状态
            if (campaign.getStatus() == null) {
                campaign.setStatus("draft");
            } else if (!isValidStatus(campaign.getStatus())) {
                throw new IllegalArgumentException("无效的状态值");
            }
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("验证广告计划数据失败", e);
        }
    }

    private boolean isValidStatus(String status) {
        return status.matches("^(draft|running|paused|completed)$");
    }

    @Override
    public PageResult<AdCampaign> findDeletedByPage(Integer page, Integer size) {
        try {
            // 计算偏移量
            int offset = (page - 1) * size;
            // 获取总记录数
            long total = adCampaignMapper.countDeleted();
            // 获取当前页数据
            List<AdCampaign> records = adCampaignMapper.findDeletedByPage(offset, size);
            records.forEach(record -> {
                record.setAdvertiser(advertiserMapper.findById(record.getAdvertiserId()));
            });
            // 返回分页结果
            return PageResult.of(records, total, size, page);
        } catch (Exception e) {
            log.error("分页查询已删除的广告计划失败", e);
            return null;
        }
    }
}
